package gspringboot

import (
	"gitee.com/hongzhaomin/gspring/core"
	"gitee.com/hongzhaomin/gspring/iface"
)

type ConfigurationApplicationContext interface {
	iface.ApplicationContext

	SetEnvironment(environment ConfigurationEnvironment)

	GetEnvironment() ConfigurationEnvironment

	SetLogger(logger iface.GspringLogger)

	GetLogger() iface.GspringLogger
}

// NewWebApplicationContext 创建 WebApplicationContext
func NewWebApplicationContext() *WebApplicationContext {
	context := &WebApplicationContext{
		CommonApplicationContext: NewCommonApplicationContext(),
	}
	// 设置子类
	context.AbstractApplicationContext.ApplicationContext = context
	return context
}

// NewCommonApplicationContext 创建 CommonApplicationContext
func NewCommonApplicationContext() *CommonApplicationContext {
	context := &CommonApplicationContext{
		DefaultApplicationContext: core.NewDefaultApplicationContext(),
	}
	// 设置子类
	context.AbstractApplicationContext.ApplicationContext = context
	return context
}

// =============================== CommonApplicationContext ===========================
var _ iface.ApplicationContext = (*CommonApplicationContext)(nil)
var _ ConfigurationApplicationContext = (*CommonApplicationContext)(nil)

type CommonApplicationContext struct {
	*core.DefaultApplicationContext

	environment ConfigurationEnvironment
	logger      iface.GspringLogger
}

func (my *CommonApplicationContext) super() iface.ApplicationContext {
	return my.DefaultApplicationContext
}

func (my *CommonApplicationContext) RefreshBeanFactory() {
	my.super().RefreshBeanFactory()
	beanFactory := my.GetBeanFactory()
	if !beanFactory.ContainsLocalBean(EnvironmentBeanName) {
		beanFactory.RegisterSingleton(EnvironmentBeanName, my.environment)
	}
	if !beanFactory.ContainsLocalBean(LoggerBeanName) {
		beanFactory.RegisterSingleton(LoggerBeanName, my.logger)
	}
}

func (my *CommonApplicationContext) SetEnvironment(environment ConfigurationEnvironment) {
	my.environment = environment
}

func (my *CommonApplicationContext) GetEnvironment() ConfigurationEnvironment {
	return my.environment
}

func (my *CommonApplicationContext) SetLogger(logger iface.GspringLogger) {
	my.logger = logger
}

func (my *CommonApplicationContext) GetLogger() iface.GspringLogger {
	return my.logger
}

// ============================= WebApplicationContext ============================
var _ iface.ApplicationContext = (*WebApplicationContext)(nil)
var _ ConfigurationApplicationContext = (*WebApplicationContext)(nil)

type WebApplicationContext struct {
	*CommonApplicationContext
}

func (my *WebApplicationContext) super() iface.ApplicationContext {
	return my.CommonApplicationContext
}

func (my *WebApplicationContext) PostProcessorBeanFactory(_ iface.ListableBeanFactory) {
	// 注册web应用服务
	my.RegisterOriginBeans([]any{GinWebApplicationServer{}})
}

func (my *WebApplicationContext) startHttpServer() {
	ginServer := my.GetBeanByName(GinWebApplicationServerBeanName).(*GinWebApplicationServer)
	ginServer.StartHttpServer()
}

func (my *WebApplicationContext) shutdown() {
	ginServer := my.GetBeanByName(GinWebApplicationServerBeanName).(*GinWebApplicationServer)
	ginServer.Shutdown()
}
